#ifndef MD5_H_FILE
#define MD5_H_FILE

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
namespace utils
{
#define MD5_DIGEST_SIZE 16
#define MD5_BLOCK_SIZE 64

/* Structure to save state of computation between the single steps.  */
struct md5_ctx
{
  uint32_t A;
  uint32_t B;
  uint32_t C;
  uint32_t D;

  uint32_t total[2];
  uint32_t buflen;
  uint32_t buffer[32];
};

/* Initialize structure containing state of computation.
   (RFC 1321, 3.3: Step 3)  */

void md5_init_ctx (struct md5_ctx *ctx);

/* Process LEN bytes of BUFFER, accumulating context into CTX.
   It is assumed that LEN % 64 == 0.  */

void md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx);
void md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx);

/* Process the remaining bytes in the internal buffer and the usual
   prolog according to the standard and write the result to RESBUF.  */

void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);

/* Copy the 4 byte value from v into the memory location pointed to by *cp,
   If your architecture allows unaligned access this is equivalent to
   * (uint32_t *) cp = v  */

void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);

/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
   result is always in little endian byte order, so that a byte-wise
   output yields to the wanted ASCII representation of the message
   digest.  */

void *md5_buffer (const char *buffer, size_t len, void *resblock);
char *md5_to_string (const char md5[MD5_DIGEST_SIZE], char *resblock);

/* Compute MD5 message digest for bytes read from STREAM.  The
   resulting message digest number will be written into the 16 bytes
   beginning at RESBLOCK.  */

int md5_stream (FILE *stream, void *resblock);
}
#endif //MD5_H_FILE